/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package alex;
//import com.google.gson.Gson;
//import com.google.gson.GsonBuilder;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;

/**
 *
 * @author Alex
 */
public class DistanceMatrix {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
    }
    
    /*PRIVATE VARS*/
	private String $wordA = "";
	private String $wordB = "";	
	private Integer $paddingA=3;//Used to get the extra spacing around the words, leave alone.
        private Integer $paddingB=3;
	private String[][] $matrix;
	private String $htmlTable="";
	
	/*-Key=>vlaue pair array-*/
	//see createHtmlTable() for use
        public Map $htmlTableAttributes = new HashMap();
	public void addTableAttribute(String $name, String $value)
	{
                this.$htmlTableAttributes.put($name,$value);
	}
	public void removeTableAttribute(String $name)
	{
                this.$htmlTableAttributes.remove($name);
	}
	public String getTableAttributes()
	{
                String returnVal = "";
                Iterator iterator = this.$htmlTableAttributes.entrySet().iterator();
                while (iterator.hasNext()) {
                        Map.Entry KeyValPair = (Map.Entry) iterator.next();
                        returnVal = returnVal+ "(" +KeyValPair.getKey()+"=>"+KeyValPair.getValue()+ ")";
                }
		return returnVal;
	}
	/*--*/
	
	/*SETTERS*/
	public void setWordA(String $a)
	{
		this.$wordA = $a;
	}
	public void setWordB(String $b)
	{
		this.$wordB = $b;
	}
	/*GETTERS*/
	public String getWordA()
	{
		return this.$wordA;
	}
	public String getWordB()
	{
		return this.$wordB;
	}
	
	/*PUBLIC METHODS*/
	//Returns String
	public String getHtmlTable()
	{
                this.$htmlTable="";
                this.$matrix=null;
		this.prepareGrid();
		this.solveGrid();
		//this.crosscheckAnswer();
                

                //Gson gson = new GsonBuilder().setPrettyPrinting().create();
                //System.out.println(gson.toJson(this.$matrix));

		this.createHtmlTable();
		return this.$htmlTable;
	}
        
        public Integer getLevenshtein()
        {
            this.$htmlTable="";
            this.$matrix=null;
            this.prepareGrid();
            this.solveGrid();
            return Integer.parseInt(this.$matrix[(this.$wordA.length()+this.$paddingA-2)][(this.$wordB.length()+this.$paddingB-2)]);
        }
	
	/*PRIVATE METHODS*/
	private void prepareGrid()
	{
            this.$matrix = new String[(this.$wordA.length()+this.$paddingA)][(this.$wordB.length()+this.$paddingB)];
            //System.out.println("Y:'"+this.$wordA+"' X:'"+this.$wordB+"'");
            //System.out.println("Y:"+this.$wordA.length()+" X:"+this.$wordB.length());
            //System.out.println("Y:"+(this.$wordA.length()+this.$paddingA)+" X:"+(this.$wordB.length()+this.$paddingB));
                for(Integer $y = 0; $y < (this.$wordA.length()+this.$paddingA); $y++)
		{
			for(Integer $x = 0; $x < (this.$wordB.length()+this.$paddingB); $x++)
			{
                                //System.out.println("SetBlank:["+$y+"]["+$x+"]");
				this.$matrix[$y][$x] = "";
				if($y==0)
				{
					if($x-1 > -1 && $x != (this.$wordB.length()+this.$paddingB-1))
					{
                                                //System.out.println("SetNumFromX");
						this.$matrix[$y][$x] =Integer.toString($x-1);
					}else if($x==(this.$wordB.length()+this.$paddingB-1))
					{
                                                //System.out.println("SetA");
						this.$matrix[$y][$x] ="A";
					}
				}
				else if($x==0)
				{
					if($y-1 > -1 && $y != (this.$wordA.length()+this.$paddingA-1))
					{
                                                //System.out.println("SetNumFromY");
						this.$matrix[$y][$x] = Integer.toString($y-1);
					}else if($y == (this.$wordA.length()+this.$paddingA-1))
					{
                                                //System.out.println("SetB");
						this.$matrix[$y][$x] = "B";
					}
				}
				else if($y==(this.$wordA.length()+this.$paddingA-1))
				{
					if($x > 1)
					{
                                                //System.out.println("Sub1");
                                                try{
						this.$matrix[$y][$x] = this.$wordB.substring($x-2,$x-1);
                                                }catch(Exception e){}
					}
				}
				else if($x==(this.$wordB.length()+this.$paddingB-1))
				{
					if($y > 1)
					{
                                                //System.out.println("Sub2");
                                                try{
						this.$matrix[$y][$x] = this.$wordA.substring($y-2,$y-1);
                                                }catch(Exception e){}
					}
				}
				
			}
		}
		this.$matrix[1][1] = "0"; //Initalize the first square to zero
	}
	private void solveGrid()
	{
		for(Integer $y = 1; $y < (this.$wordA.length()+this.$paddingA-1); $y++)
		{
				for(Integer $x = 1; $x < (this.$wordB.length()+this.$paddingB-1); $x++)
				{
				if($y + $x !=2)
				{
					if(this.$matrix[$y][(this.$wordB.length()+this.$paddingB-1)].equals(this.$matrix[(this.$wordA.length()+this.$paddingA-1)][$x]))
					{
						this.$matrix[$y][$x] = this.$matrix[$y-1][$x-1];
					}else
					{
						this.$matrix[$y][$x] = Integer.toString(Math.min(Integer.parseInt(this.$matrix[$y][$x-1]),Integer.parseInt(this.$matrix[$y-1][$x])) +1);
					}
				}
			}
		}
	}
	/*private void crosscheckAnswer()
	{
		if(this.$matrix[(this.$wordA.length()+this.$padding-2)][(this.$wordB.length()+this.$padding-2)] == levenshtein(this.$wordA, this.$wordB))
		{
			return true;
		}
		else
		{
			die("Error, php levenshtein did not match progmatic grid calculation");
			return false;
		}
	}*/
	private void createHtmlTable()
	{
                this.$htmlTable += "<table";
                Iterator iterator = this.$htmlTableAttributes.entrySet().iterator();
                while (iterator.hasNext()) {
                       Map.Entry KeyValPair = (Map.Entry) iterator.next();
                       this.$htmlTable +=" "+KeyValPair.getKey()+"=\""+KeyValPair.getValue()+"\"";
                }
                this.$htmlTable += ">";
                
		
		for (Integer $y = 0; $y < this.$matrix.length; $y++)
		{
			this.$htmlTable += "<tr>";
			for(Integer $x = 0; $x < this.$matrix[$y].length; $x++)
			{
				this.$htmlTable += "<td class=\"c"+$x+" r"+$y+"\">";
				this.$htmlTable += this.$matrix[$y][$x];
				this.$htmlTable += "</td>";
			}
			this.$htmlTable += "</tr>";
		}
		this.$htmlTable +="</table>";
	}
}
